package com.pureut.equipment.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 时间工具类
 */
public class TimeUtils {

    /**
     * 计算两个日期之间相差多少小时
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDifferHour(Date startDate, Date endDate) {
        long dayM = 1000 * 24 * 60 * 60;
        long hourM = 1000 * 60 * 60;
        long differ = endDate.getTime() - startDate.getTime();
        long hour = differ % dayM / hourM + 24 * (differ / dayM);
        return Integer.parseInt(String.valueOf(hour));
    }

    /**
     * 计算两个时间相差多少天
     */
    public static int getDifferDays(Date startDate, Date endDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //跨年不会出现问题
        //如果时间为：2016-03-18 11:59:59 和 2016-03-19 00:00:01的话差值为 0
        String format = sdf.format(startDate);
        String format1 = sdf.format(endDate);
        Date fDate = sdf.parse(format);
        Date oDate = sdf.parse(format1);
        long days = (oDate.getTime() - fDate.getTime()) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(days));
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) throws ParseException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sf.format(nowTime);
        Date parseNowTime = sf.parse(format);

        String format1 = sf.format(startTime);
        Date parseStartTime = sf.parse(format1);

        String format2 = sf.format(endTime);
        Date parseEndTime = sf.parse(format2);


        if (parseNowTime.getTime() == parseStartTime.getTime()
                || parseNowTime.getTime() == parseEndTime.getTime()) {
            return false;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(parseNowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(parseStartTime);

        Calendar end = Calendar.getInstance();
        end.setTime(parseEndTime);

        return date.after(begin) && date.before(end);
    }

    /**
     * 判断当前日期是星期几
     * return 数字1,2,3,4,5,6,7
     */
    public static int dayForWeek(String pTime) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(format.parse(pTime));
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    /**
     * 根据时间获取月的第几周
     *
     * @param sourceTime
     * @return
     */
    public static String getMonthNoAndWeekNo(LocalDateTime sourceTime) {
        Date date = Date.from(sourceTime.atZone(ZoneId.systemDefault()).toInstant());
        return join(date);
    }

    /**
     * 根据时间获取月的第几周
     *
     * @param sourceTime
     * @return
     */
    public static String getMonthNoAndWeekNo(LocalDate sourceTime) {
        Date date = Date.from(sourceTime.atStartOfDay(ZoneOffset.ofHours(8)).toInstant());
        return join(date);
    }

    /**
     * 根据时间获取月的第几周
     *
     * @param date
     * @return
     */
    public static String getMonthNoAndWeekNo(Date date) {
        return join(date);
    }

    /**
     * 拼接
     *
     * @param date
     * @return
     */
    public static String join(Date date) {
        return getMonth(date) + "-" + getWeek(date);
    }

    /**
     * 获取第几月
     *
     * @param date 时间
     * @return
     */
    public static int getMonth(Date date) {
        return toCalendar(date).get(Calendar.MONTH);
    }

    /**
     * 获取第几周
     *
     * @param date 时间
     * @return
     */
    public static int getWeek(Date date) {
        return toCalendar(date).get(Calendar.WEEK_OF_MONTH);
    }

    /**
     * 万年历
     *
     * @param date
     * @return
     */
    public static Calendar toCalendar(Date date) {
        Calendar cal = Calendar.getInstance(Locale.getDefault(Locale.Category.FORMAT));
        cal.setFirstDayOfWeek(Calendar.WEEK_OF_MONTH);
        cal.setTime(date);
        return cal;
    }

    /**
     * 获取时间是本年的第几周
     *
     * @param date
     * @return
     */
    public static int getWeekNumber(Date date) {
        Calendar calendar = Calendar.getInstance();
        //设置星期一为一周开始的第一天
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        //获得当前的时间戳
        long time = date.getTime();
        calendar.setTimeInMillis(time);
        //获得当前日期属于今年的第几周
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * date2比date1多的周数
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static int calcWeekOffset(Date startTime, Date endTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(startTime);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        dayOfWeek = dayOfWeek - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        int dayOffset = calcDayOffset(startTime, endTime);
        int weekOffset = dayOffset / 7;
        int a;
        if (dayOffset > 0) {
            a = (dayOffset % 7 + dayOfWeek > 7) ? 1 : 0;
        } else {
            a = (dayOfWeek + dayOffset % 7 < 1) ? -1 : 0;
        }
        weekOffset = weekOffset + a;
        return weekOffset;
    }

    public static int calcDayOffset(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) {  //同一年
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {  //闰年
                    timeDistance += 366;
                } else {  //不是闰年

                    timeDistance += 365;
                }
            }
            return timeDistance + (day2 - day1);
        } else { //不同年
            return day2 - day1;
        }
    }
}
